package com.gdth.widget.scrollview;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.gdth.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import android.widget.ImageView.ScaleType;

public class ImageScrollView extends ScrollView implements OnTouchListener {  

	private Context mContext;
    /** 
     * 每页要加载的图片数量 
     */  
    public static final int PAGE_SIZE = 15;  
  
    /** 
     * current page
     */  
    private int page;  
  
    /** 
     * everyone column width 
     */  
    private static int columnWidth;   
  
    /** 
     * second column height
     */  
    private int firstColumnHeight, secondColumnHeight, thirdColumnHeight;   
  
    /** 
     * column layout
     */  
    private LinearLayout firstColumn, secondColumn, thirdColumn;   

    /** 
     * 是否已加载过一次layout，这里onLayout中的初始化只需加载一次 
     */  
    private boolean loadOnce;
    
    /** 
     * 记录所有正在下载或等待下载的任务。 
     */  
    private static Set<LoadImageTask> taskCollection;  
  
    /** 
     * MyScrollView下的直接子布局。 
     */  
    private static View scrollLayout;  
  
    /** 
     * MyScrollView布局的高度。 
     */  
    private static int scrollViewHeight;  
  
    /** 
     * 记录上垂直方向的滚动距离。 
     */  
    private static int lastScrollY = -1;  
    
    private String[] imageUrls;
  
    /** 
     * 记录所有界面上的图片，用以可以随时控制对图片的释放。 
     */  
    private static List<ImageView> imageViewList;  
  
    /** 
     * 在Handler中进行图片可见性检查的判断，以及加载更多图片的操作。 
     */  
    private Handler handler = new Handler(new Handler.Callback(){

		@Override
		public boolean handleMessage(Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what){
				case 1:
					ImageScrollView myScrollView = (ImageScrollView) msg.obj;  
		            int scrollY = myScrollView.getScrollY();  
		            // 如果当前的滚动位置和上次相同，表示已停止滚动  
		            if (scrollY == lastScrollY) {  
		                // 当滚动的最底部，并且当前没有正在下载的任务时，开始加载下一页的图片  
		                if (scrollViewHeight + scrollY >= scrollLayout.getHeight()  
		                        && taskCollection.isEmpty()) {  
		                    myScrollView.loadMoreImages();  
		                }  
		                myScrollView.checkVisibility();  
		            } else {  
		                lastScrollY = scrollY;  
		                Message message = new Message();  
		                message.obj = myScrollView;
		                
		                // 5毫秒后再次对滚动位置进行判断  
		                handler.sendMessageDelayed(message, 5);  
		            }
		            break;
				case 2:
					Bundle mBundle = msg.getData();
					String mImageUrl = mBundle.getString("url");
					int imageKey = mBundle.getInt("key");
					
					Bitmap mBitmap = ImageLoader.getInstance().getBitmapFromMemoryCache(mImageUrl);
					
					  
		            double ratio = mBitmap.getWidth() / (columnWidth * 1.0);  
		            int imageHeight = (int) (mBitmap.getHeight() / ratio);
					
					
			        if (imageKey != -1) {
			        	ImageView mImageView = imageViewList.get(imageKey);
			            mImageView.setImageBitmap(mBitmap);
			        } else {  
			            ImageView imageView = new ImageView(mContext); 
			            
			            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(columnWidth, imageHeight);
			            imageView.setLayoutParams(params);  
			            imageView.setImageBitmap(mBitmap);  
			            imageView.setScaleType(ScaleType.FIT_XY);  
			            imageView.setPadding(5, 5, 5, 5);  
			            imageView.setTag(R.string.image_url, mImageUrl);
			            
			            findColumnToAdd(imageView, imageHeight);
			        }  
			        
			        taskCollection.remove(this);  
					break;
			}
			return false;
		}
    	
    });

    /**
     * constructor
     * @param context
     */
    public ImageScrollView(Context mContext, String[] imageUrls){
    	super(mContext);
    	
    	this.mContext = mContext;
    	this.imageUrls = imageUrls;
    	initView();
    }
    /** 
     * constructor
     * @param context 
     * @param attrs 
     */  
    public ImageScrollView(Context mContext, AttributeSet attrs, String[] imageUrls) {  
        super(mContext, attrs); 
        
        this.mContext = mContext;
        this.imageUrls = imageUrls;
        initView();
    }
    
    private void initView(){
    	imageViewList = new ArrayList<ImageView>(); 
        taskCollection = new HashSet<LoadImageTask>();
        
    	setOnTouchListener(this); 
    }
  
    /** 
     * 进行一些关键性的初始化操作，获取MyScrollView的高度，以及得到第一列的宽度值。并在这里开始加载第一页的图片。 
     */  
    @Override  
    protected void onLayout(boolean changed, int l, int t, int r, int b) {  
        super.onLayout(changed, l, t, r, b);  
        if (changed && !loadOnce) {  
            scrollViewHeight = getHeight();  
            scrollLayout = getChildAt(0);  
            firstColumn = new LinearLayout(this.mContext);//(LinearLayout) findViewById(R.id.first_column);  
            secondColumn = new LinearLayout(this.mContext);//(LinearLayout) findViewById(R.id.second_column);  
            thirdColumn = new LinearLayout(this.mContext);//(LinearLayout) findViewById(R.id.third_column);  
            
            this.addView(firstColumn);
            this.addView(secondColumn);
            this.addView(thirdColumn);
            
            columnWidth = firstColumn.getWidth();
            loadOnce = true;  
            loadMoreImages();  
        }  
    }  
  
    /** 
     * 监听用户的触屏事件，如果用户手指离开屏幕则开始进行滚动检测。 
     */  
    @Override  
    public boolean onTouch(View v, MotionEvent event) {  
        if (event.getAction() == MotionEvent.ACTION_UP) {  
            Message message = new Message();
            message.what = 1;
            message.obj = this;  
            handler.sendMessageDelayed(message, 5);  
        }  
        return false;  
    }  
  
    /** 
     * 开始加载下一页的图片，每张图片都会开启一个异步线程去下载。 
     */  
    public void loadMoreImages() {  
        if (hasSDCard()) {  
            int startIndex = page * PAGE_SIZE;  
            int endIndex = page * PAGE_SIZE + PAGE_SIZE;  
            if (startIndex < imageUrls.length) {  
                Toast.makeText(getContext(), "正在加载...", Toast.LENGTH_SHORT).show();  
                if (endIndex > imageUrls.length) {  
                    endIndex = imageUrls.length;  
                }  
                for (int i = startIndex; i < endIndex; i++) {  
                    LoadImageTask task = new LoadImageTask(columnWidth);  
                    taskCollection.add(task);  
                    task.execute(imageUrls[i]);  
                }  
                page++;  
            } else {  
                Toast.makeText(getContext(), "已没有更多图片", Toast.LENGTH_SHORT).show();  
            }  
        } else {  
            Toast.makeText(getContext(), "未发现SD卡", Toast.LENGTH_SHORT).show();  
        }  
    }

    /** 
     * 找到此时应该添加图片的一列。原则就是对三列的高度进行判断，当前高度最小的一列就是应该添加的一列。  
     * @param imageView 
     * @param imageHeight 
     * @return 应该添加图片的一列 
     */  
    private void findColumnToAdd(ImageView imageView, int imageHeight) {  
        if (firstColumnHeight <= secondColumnHeight) {  
            if (firstColumnHeight <= thirdColumnHeight) {  
                imageView.setTag(R.string.border_top, firstColumnHeight);  
                firstColumnHeight += imageHeight;  
                imageView.setTag(R.string.border_bottom, firstColumnHeight);  
                firstColumn.addView(imageView);  
            }  
            imageView.setTag(R.string.border_top, thirdColumnHeight);  
            thirdColumnHeight += imageHeight;  
            imageView.setTag(R.string.border_bottom, thirdColumnHeight);  
            thirdColumn.addView(imageView);  
        } else {  
            if (secondColumnHeight <= thirdColumnHeight) {  
                imageView.setTag(R.string.border_top, secondColumnHeight);  
                secondColumnHeight += imageHeight;  
                imageView.setTag(R.string.border_bottom, secondColumnHeight); 
                
                secondColumn.addView(imageView);  
            }  
            imageView.setTag(R.string.border_top, thirdColumnHeight);  
            thirdColumnHeight += imageHeight;  
            imageView.setTag(R.string.border_bottom, thirdColumnHeight);
            
            thirdColumn.addView(imageView);  
        }
        
        imageViewList.add(imageView);
    }  

    /** 
     * 遍历imageViewList中的每张图片，对图片的可见性进行检查，如果图片已经离开屏幕可见范围，则将图片替换成一张空图。 
     */  
    public void checkVisibility() {  
        for (int i = 0; i < imageViewList.size(); i++) {  
            ImageView imageView = imageViewList.get(i);  
            int borderTop = (Integer) imageView.getTag(R.string.border_top);  
            int borderBottom = (Integer) imageView.getTag(R.string.border_bottom);  
            if (borderBottom > getScrollY()  
                    && borderTop < getScrollY() + scrollViewHeight) {  
                String imageUrl = (String) imageView.getTag(R.string.image_url);  
                Bitmap bitmap = ImageLoader.getInstance().getBitmapFromMemoryCache(imageUrl);  
                if (bitmap != null) {  
                    imageView.setImageBitmap(bitmap);  
                } else {  
                    LoadImageTask task = new LoadImageTask(i);
                    task.execute(imageUrl);  
                }  
            } else {  
                imageView.setImageResource(R.drawable.listview_item_img);  
            }  
        }  
    }  
  
    /** 
     * 判断手机是否有SD卡
     * @return 有SD卡返回true，没有返回false。 
     */  
    private boolean hasSDCard() {  
        return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());  
    }
}
